package com.bridgeintelligent.tag.combination.service;

import com.bridgeintelligent.tag.combination.entity.CombinationPage;
import com.bridgeintelligent.tag.combination.mapper.CombinationMapper;
import com.bridgeintelligent.tag.combination.pojo.Combination;
import com.bridgeintelligent.tag.constants.ExceptionCodes;
import com.bridgeintelligent.tag.constants.Permissions;
import com.bridgeintelligent.tag.constants.TagConstants;
import com.bridgeintelligent.tag.user.mgmt.pojo.User;
import com.bridgeintelligent.tag.utils.SecurityHelper;
import com.bridgeintelligent.tag.webserver.security.TagSecurityHelper;
import com.bridgeintelligent.tag.webserver.workflow.*;
import com.bridgeintelligent.tag.webserver.workflow.repository.InstanceMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wayneleo.quickstart.framework.IDGenerator;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 组合标签审批服务层实现
 */
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class CombinationApprovalService implements ICombinationApprovalService {

    private SubmitterService submitterService;

    private CombinationMapper combinationMapper;

    private ApproverService approverService;

    private CombinationService combinationService;

    private InstanceMapper instanceMapper;

    @Override
    public void addCommit(String dimId) {

        Instance submit = submitterService.submit(new SubmitterService.SubmitParam().setResourceId(dimId).setWorkflowId(TagConstants.Workflow.ID_10007));
        Map<String ,String> map = new HashMap();
        map.put("approvalStatus", "2");
        map.put("combinationId", dimId);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        map.put("applicationTime",sdf.format(new Date()));//申请时间

        User user = TagSecurityHelper.currentUser();
        map.put("applicant",user.getUserId());//申请人
        map.put("applicantName",user.getName());

        combinationMapper.updateComStatus(map);
        if(SecurityHelper.containsPermission(Permissions.WORKFLOW_DEFINITION_10012.getCode())){
            try{
                this.addPass(dimId, submit.getId());
            }catch (Exception e){
                log.error("自动审核 发布组合标签 出错", e);
            }
        }

    }

    /**
     * 新增组合标签审批通过
     *
     * @param dimId
     */
    @Override
    public void addPass(String dimId,String instanceId) {
        //Instance instance = findInstance(dimId);
        Instance pass = approverService.pass(instanceId);
        //修改审批状态
        Map<String,String> map = new HashMap();
        map.put("approvalStatus", pass.getCurrentStatus()+"");
        map.put("combinationId", dimId);
        User user = TagSecurityHelper.currentUser();
        map.put("approver",user.getUserId());//审批人
        map.put("approverName",user.getName());

        combinationMapper.updateComStatus(map);

        combinationService.addDimData(dimId);

    }

    /**
     * 审批驳回
     *
     * @param dimId
     */
    @Override
    public void reject(String dimId, String instanceId, String desc) {
        //Instance instance = findInstance(dimId);
        Instance reject = approverService.reject(instanceId, desc);
        //修改审批状态
        Map<String,String> map = new HashMap();
        map.put("approvalStatus", reject.getCurrentStatus()+"");
        map.put("combinationId", dimId);
        User user = TagSecurityHelper.currentUser();
        map.put("approver",user.getUserId());//审批人
        map.put("approverName",user.getName());
        map.put("reject",desc);//驳回意见
        combinationMapper.updateComStatus(map);
    }

    /**
     * 重新提交审批
     *
     * @param dimId
     */
    @Override
    public void resubmit(String dimId) {
        //Map<String, Instance> map = submitterService.fetchByResources(new SubmitterService.FetchByResourcesParam().addResourceId(dimId).setContainsDeleted(false).setCurrentStatus(Status.REJECTED.code()));
        //Instance instance = map.get(dimId);
        Map<String ,String > map = new HashMap<>();
        User user = TagSecurityHelper.currentUser();
        map.put("userId",user.getUserId());
        map.put("resourceId",dimId);
        map.put("workflowId",TagConstants.Workflow.ID_10007);
        Instance instance = instanceMapper.findInstance(map);

        Instance submit = submitterService.submit(new SubmitterService.SubmitParam()
                .setInstanceId(instance.getId())
                .setResourceId(dimId)
                .setWorkflowId(instance.getWorkflowId())
        );
        Map<String ,String> map1 = new HashMap();
        map1.put("approvalStatus", submit.getCurrentStatus()+"");
        map1.put("combinationId", dimId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        map1.put("applicationTime",sdf.format(new Date()));//申请时间
        map1.put("applicant",user.getUserId());//申请人
        map1.put("applicantName",user.getName());
        map1.put("reject","-");//将驳回意见变成-

        combinationMapper.updateComStatus(map1);
        if(SecurityHelper.containsPermission(Permissions.WORKFLOW_DEFINITION_10012.getCode())){
            try{
                this.addPass(dimId, submit.getId());
            }catch (Exception e){
                log.error("自动审核 发布组合标签 出错", e);
            }
        }

    }

    /**
     * 获取审批列表
     *
     * @param pageNumber
     * @param pageSize
     * @param dimName
     * @param approveType
     * @param approveState
     * @param uptTimeStart
     * @param uptTimeEnd
     */
    @Override
    public CombinationPage<Combination> findList(Integer pageNumber, Integer pageSize, String dimName, String approveType, String approveState, String uptTimeStart, String uptTimeEnd) {
        //获取权限id
        List<String> workflowIds = findInstanceByPower(approveType);
        if (CollectionUtils.isEmpty(workflowIds)) {
            workflowIds.add(IDGenerator.gen());
        }
        Map map = new HashMap();
        map.put("dimName", dimName);
        map.put("approveState", approveState);
        map.put("uptTimeStart", uptTimeStart);
        if (uptTimeEnd != null && !"".equals(uptTimeEnd)) {
            map.put("uptTimeEnd", uptTimeEnd + "23.59.59");
        }
        map.put("workflowIds", workflowIds);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(calendar.MONTH, -2);
        String temp = format(calendar.getTime());
        Page page = PageHelper.startPage(pageNumber, pageSize);

        List<Combination> list = combinationMapper.findComApproveList(map);
        if (CollectionUtils.isNotEmpty(list)) {
            for (Combination combination : list) {
                if (Integer.toString(Status.WAITTING.code()).equals(combination.getApprovalStatus())) {
                    combination.setApprovalStatusName(Status.WAITTING.info());
                } else if (Integer.toString(Status.REJECTED.code()).equals(combination.getApprovalStatus())) {
                    combination.setApprovalStatusName(Status.REJECTED.info());
                } else if (Integer.toString(Status.PASSED.code()).equals(combination.getApprovalStatus())) {
                    combination.setApprovalStatusName(Status.PASSED.info());
                }
                if (temp.compareTo(combination.getUptTime()) < 1) {
                    combination.setIsnew(true);
                } else {
                    combination.setIsnew(false);
                }
                combination.setOwnerName(combinationMapper.getName(combination.getOwnerId()));
            }
        }
        CombinationPage<Combination> combinationPage = new CombinationPage<>();
        combinationPage.setContent(list);
        combinationPage.setTotalPages(page.getPages());
        combinationPage.setTotalElements(page.getTotal());
        combinationPage.setSize(page.getPageSize());
        combinationPage.setRequestPager(pageNumber);
        return combinationPage;
    }

    /**
     * 获取所有的申请类型
     */
    @Override
    public Map findApproveType() {
        Map map = new HashMap();
        map.put(TagConstants.Workflow.ID_10007, Permissions.of(TagConstants.Workflow.ID_10007).getName());
        return map;
    }


    /**
     * 获取流程实例对象
     *
     * @param dimId
     * @return
     */
    public Instance findInstance(String dimId) {
        Map<String, Instance> map = submitterService.fetchByResources(new SubmitterService.FetchByResourcesParam().addResourceId(dimId).setContainsDeleted(false).setCurrentStatus(Status.WAITTING.code()));
        Set<Map.Entry<String, Instance>> entries = map.entrySet();
        for (Map.Entry<String, Instance> e : entries) {
            String resource = e.getValue().getResource();
            System.out.println("测试打印================1" + resource);
            System.out.println("测试打印================2" + e.getValue().getId());

        }
        Instance instance = map.get(dimId);
        return instance;
    }

    /**
     * 获取用户有权审批的流程实例
     *
     * @return
     */
    public List<String> findInstanceByPower(String workflowId) {
        List<String> workflowIds = new ArrayList<>();
        if (StringUtils.isEmpty(workflowId)) {
            for (String workflowDefinitionId : TagConstants.Workflow.values()) {
                if (SecurityHelper.containsPermission(workflowDefinitionId)) {
                    workflowIds.add(workflowDefinitionId);
                }
            }
        } else {
            if (!SecurityHelper.containsPermission(workflowId)) {
                User user = SecurityHelper.currentUser();
                throw new WorkflowException((ExceptionCodes.WORKFLOW_20006.args(user.getUserId(), workflowId)));
            }
            workflowIds.add(workflowId);
        }

        return workflowIds;
    }

    private static String format(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return sdf.format(date);
        } catch (Exception e) {
            return null;
        }
    }

}
